import sys

from PySide6.QtCore import Signal
from PySide6.QtGui import QStandardItemModel, QStandardItem
from PySide6.QtWidgets import QApplication, QMainWindow, QTableView, QHeaderView, QGraphicsView, QGraphicsScene, \
    QGraphicsProxyWidget, QPushButton, QVBoxLayout, QWidget


class 数据表格组件(QGraphicsProxyWidget):
    # 定义数据变更信号
    数据变更信号 = Signal(int, int, str)

    def __init__(self, 标题=None, 同步函数=None):
        super().__init__()

        # 创建主小部件和布局
        self.主小部件 = QWidget()
        self.布局 = QVBoxLayout(self.主小部件)

        # 如果提供了同步函数，则将信号连接到该函数
        self.同步函数 = 同步函数

        # 创建QTableView
        self.表格视图 = QTableView()

        # 初始化模型
        self.模型 = QStandardItemModel()
        if 标题:
            self.模型.setHorizontalHeaderLabels(标题)

        self.表格视图.setModel(self.模型)

        # 设置列宽自动填充
        self.表格视图.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        self.表格视图.setSelectionBehavior(QTableView.SelectItems)
        self.表格视图.setSelectionMode(QTableView.ExtendedSelection)

        # 将QTableView添加到布局
        self.布局.addWidget(self.表格视图)

        # 创建添加行的按钮并绑定功能
        self.添加行按钮 = QPushButton("添加行")
        self.添加行按钮.clicked.connect(self.添加行)
        self.布局.addWidget(self.添加行按钮)

        # 将主小部件设置为代理小部件的部件
        self.setWidget(self.主小部件)

        # 连接模型的变更信号到同步触发器
        self.模型.itemChanged.connect(self.同步触发器)

    def 获取单元格内容(self, 行, 列):
        """获取指定单元格的内容"""
        项 = self.模型.item(行, 列)
        return 项.text() if 项 else ""

    def 设置单元格内容(self, 行, 列, 内容):
        """设置指定单元格的内容"""
        项 = QStandardItem(内容)
        self.模型.setItem(行, 列, 项)

    def 添加行(self):
        """在表格中添加一个空白行"""
        行号 = self.模型.rowCount()
        self.模型.insertRow(行号)
        self.自动调整大小()

    def 设置数据(self, 数据):
        """将数据直接加载到现有模型中，而不是替换模型"""
        self.模型.clear()
        # 设置标题
        self.模型 = 数据
        self.表格视图.setModel(self.模型)
        self.模型.itemChanged.connect(self.同步触发器)
        self.自动调整大小()

    def 同步触发器(self, item):
        """处理模型中的数据变更事件，获取行、列和内容"""
        行 = item.row()
        列 = item.column()
        内容 = item.text()
        # 触发数据变更信号，包含行、列和新内容
        操作类型 = "修改"
        if self.同步函数:
            self.同步函数(行, 列, 内容, 操作类型)
        self.自动调整大小()

    def 自动调整大小(self):
        """根据内容自动调整表格组件的大小"""
        # 计算表格视图的合适高度
        行数 = self.模型.rowCount()
        列数 = self.模型.columnCount()
        行高 = self.表格视图.verticalHeader().defaultSectionSize() if 行数 > 0 else 0
        标题高度 = self.表格视图.horizontalHeader().height()
        按钮高度 = self.添加行按钮.height()

        总高度 = 行数 * 行高 + 标题高度 + 按钮高度

        # 计算表格视图的合适宽度
        列宽 = self.表格视图.horizontalHeader().defaultSectionSize() if 列数 > 0 else 0
        总宽度 = 列数 * 列宽

        # 设置表格视图的大小
        self.表格视图.setFixedSize(总宽度, 总高度)

        # 调整主小部件的大小
        self.主小部件.adjustSize()

def 同步函数(行, 列, 内容, 操作类型=None):
    """同步处理函数，响应组件内的数据变更"""
    print(f"数据已同步 - 行: {行}, 列: {列}, 内容: {内容}, 操作类型: {操作类型}")

if __name__ == "__main__":
    app = QApplication(sys.argv)

    main_window = QMainWindow()
    scene = QGraphicsScene()
    view = QGraphicsView(scene)
    main_window.setCentralWidget(view)

    # 创建数据表格组件实例
    数据表格 = 数据表格组件(标题=["键", "值"], 同步函数=同步函数)
    scene.addItem(数据表格)

    # 设置一些初始数据
    数据 = QStandardItemModel()
    数据.setHorizontalHeaderLabels(["键", "值"])
    数据.appendRow([QStandardItem("键1"), QStandardItem("值1")])
    数据.appendRow([QStandardItem("键2"), QStandardItem("值2")])
    数据表格.设置数据(数据)

    main_window.show()
    sys.exit(app.exec())